﻿using AntUnion.FrameWork.Model.Models;
using AntUnion.FrameWork.Util;
using AntUnion.FrameWork.Web.IService;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Filters;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Linq;

namespace AntUnion.FrameWork.Web.Service
{
    public class LogService : ILogService
    {
        /// <summary>
        /// 填写平台操作日志
        /// </summary>
        /// <param name="cont"></param>
        /// <param name="userid"></param>
        /// <param name="username"></param>
        /// <param name="userType"></param>
        /// <returns></returns>
        public int WriteLog(string cont, int userid, string username, UserType userType)
        {
            try
            {
                using (mtContext mtContext = new mtContext())
                {
                    mtContext.TbLogs.Add(new TbLog()
                    {
                        Operator = userid,
                        Name = username,
                        Cont = cont,
                        Source = (int)userType,
                        Addtime = System.DateTime.Now
                    });
                    return mtContext.SaveChanges();
                }
            }
            catch (System.Exception)
            {
                throw;
            }
        }


        public void AddLoginLogs(HttpContext httpContext, string loginName, int operatorId, int state, string cont, string ip, string ipAddress, int source)
        {
            using (mtContext _context = new mtContext())
            {
                string system = GetOSNameByUserAgent(httpContext);
                string browser = GetSecChUa(httpContext);
                LoginLog log = new LoginLog
                {
                    Name = loginName,
                    Cont = cont,
                    Operator = operatorId,
                    Source = source,
                    State = state,
                    Ipaddress = ipAddress,
                    Ip = ip,
                    System = system,
                    Browser = browser,
                    Addtime = DateTimeUtil.Now
                };
                _context.LoginLogs.Add(log);
                _context.SaveChanges();
            }
        }

        public void AddOperatorLogs(ActionExecutingContext filterContext, string loginName, int operatorId, int source, string cont = "")
        {
            using (mtContext _context = new mtContext())
            {
                string areaName = "";
                string controllerName = "";
                string actionName = "";
                string path = filterContext.HttpContext.Request.Path.Value;
                var routeValues = filterContext.ActionDescriptor.RouteValues;
                if (path.Contains("Login"))
                {
                    return;
                }
                string ip = filterContext.HttpContext.Connection.RemoteIpAddress.ToString();
                string ipAddress = "";
                if (ip != "::1")
                {
                    string[] ips = ip.Split('.');
                    if (ips.Length == 4)
                    {
                        try
                        {
                            IPModel iPModel = HttpUtil.HttpGet($"http://whois.pconline.com.cn/ipJson.jsp?ip={ip}&json=true").ToObject<IPModel>();
                            ipAddress = iPModel.addr;
                        }
                        catch
                        {
                            ipAddress = "";
                        }
                    }
                }
                if (ip.Contains("::"))
                {
                    var realip = filterContext.HttpContext.Request.Headers["X-Real-IP"].FirstOrDefault();
                    if (realip != null)
                    {
                        ip = realip;
                        try
                        {
                            IPModel iPModel = HttpUtil.HttpGet($"http://whois.pconline.com.cn/ipJson.jsp?ip={ip}&json=true").ToObject<IPModel>();
                            ipAddress = iPModel.addr;
                        }
                        catch
                        {
                            ipAddress = "";
                        }
                    }
                }
                foreach (var item in routeValues)
                {
                    switch (item.Key)
                    {
                        case "area":
                            areaName = item.Value;
                            break;
                        case "controller":
                            controllerName = item.Value;
                            break;
                        case "action":
                            actionName = item.Value;
                            break;
                    }
                }
                string operationType = "";
                if (actionName.ToLower().Contains("get"))
                {
                    operationType = "view";
                }
                else if (actionName.ToLower().Contains("create") || actionName.ToLower().Contains("add"))
                {
                    operationType = "addNew";
                }
                else if (actionName.ToLower().Contains("edit") || actionName.ToLower().Contains("update") || actionName.ToLower().Contains("set"))
                {
                    operationType = "edit";
                }
                else if (actionName.ToLower().Contains("del") || actionName.ToLower().Contains("remove"))
                {
                    operationType = "del";
                }
                else
                {
                    return;
                }
                string param = "";
                if (filterContext.HttpContext.Request.Method == "GET")
                {
                    param = JsonConvert.SerializeObject(filterContext.HttpContext.Request.Query);
                }
                else if (filterContext.HttpContext.Request.Method == "POST")
                {
                    try
                    {
                        param = JsonConvert.SerializeObject(filterContext.HttpContext.Request.Form.Keys);
                    }
                    catch (System.Exception)
                    {
                        param = "";
                    }
                }
                OperationLog log = new OperationLog
                {
                    Cont = cont,
                    Operator = operatorId,
                    Name = loginName,
                    Source = source,
                    Addtime = DateTimeUtil.Now,
                    Ip = ip,
                    Ipaddress = ipAddress,
                    State = 1,
                    Module = controllerName,
                    Type = operationType,
                    Url = path,
                    Function = actionName,
                    Param = param
                };
                _context.OperationLogs.Add(log);
                if (operationType == "view")
                {
                    _context.SaveChanges();
                }
            }
        }

        /// <summary>
        /// 获取操作系统的名字
        /// </summary>
        /// <param name="userAgent"></param>
        /// <returns></returns>
        public static string GetOSNameByUserAgent(HttpContext httpContext)
        {
            string userAgent = httpContext.Request.Headers["User-Agent"];
            string osVersion = "未知";

            if (userAgent.Contains("NT 10.0"))
            {
                osVersion = "Windows 10";
            }
            else if (userAgent.Contains("NT 6.3"))
            {
                osVersion = "Windows 8.1";
            }
            else if (userAgent.Contains("NT 6.2"))
            {
                osVersion = "Windows 8";
            }
            else if (userAgent.Contains("NT 6.1"))
            {
                osVersion = "Windows 7";
            }
            else if (userAgent.Contains("NT 6.0"))
            {
                osVersion = "Windows Vista/Server 2008";
            }
            else if (userAgent.Contains("NT 5.2"))
            {
                if (userAgent.Contains("64"))
                    osVersion = "Windows XP";
                else
                    osVersion = "Windows Server 2003";
            }
            else if (userAgent.Contains("NT 5.1"))
            {
                osVersion = "Windows XP";
            }
            else if (userAgent.Contains("NT 5"))
            {
                osVersion = "Windows 2000";
            }
            else if (userAgent.Contains("NT 4"))
            {
                osVersion = "Windows NT4";
            }
            else if (userAgent.Contains("Me"))
            {
                osVersion = "Windows Me";
            }
            else if (userAgent.Contains("98"))
            {
                osVersion = "Windows 98";
            }
            else if (userAgent.Contains("95"))
            {
                osVersion = "Windows 95";
            }
            else if (userAgent.Contains("Mac"))
            {
                osVersion = "Mac";
            }
            else if (userAgent.Contains("Unix"))
            {
                osVersion = "UNIX";
            }
            else if (userAgent.Contains("Linux"))
            {
                osVersion = "Linux";
            }
            else if (userAgent.Contains("SunOS"))
            {
                osVersion = "SunOS";
            }
            else
            {
                osVersion = userAgent;
            }
            return osVersion;
        }

        public static string GetSecChUa(HttpContext httpContext)
        {
            if (!httpContext.Request.Headers.ContainsKey("Sec-Ch-Ua"))
            {
                return "";
            }
            string[] SecChUas = httpContext.Request.Headers["Sec-Ch-Ua"].ToString().Split(";");
            if (SecChUas.Length == 5)
            {
                return $"{SecChUas[0]} {SecChUas[4]}";
            }
            return "";
        }
    }
}
